/**
 * 
 */

package br.com.dp.dao.generico;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

/**
 * @author emmanuel
 */
public abstract class DAOImpl<ENTIDADE,CHAVEPRIMARIA extends Serializable> implements DAO<ENTIDADE,CHAVEPRIMARIA>
{

   private final static String UNIT_NAME = "depassagemDS";

   @PersistenceContext(unitName = UNIT_NAME)
   private EntityManager em;

   private Class<ENTIDADE> classeEntidade;

   public DAOImpl(Class<ENTIDADE> entityClass)
   {
      this.classeEntidade = entityClass;
   }

   public void salvar(ENTIDADE entidade)
   {
      em.persist(entidade);
   }

   public void excluir(CHAVEPRIMARIA id, Class<ENTIDADE> classe)
   {
      ENTIDADE entidadeRemovida = em.getReference(classe, id);
      em.remove(entidadeRemovida);
   }

   public ENTIDADE atualizar(ENTIDADE entidade)
   {
      return em.merge(entidade);
   }

   public ENTIDADE buscarPorId(CHAVEPRIMARIA id)
   {
      return em.find(classeEntidade, id);
   }

   @SuppressWarnings({"unchecked", "rawtypes"})
   public List<ENTIDADE> buscarTodos()
   {
      CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
      cq.select(cq.from(classeEntidade));
      return em.createQuery(cq).getResultList();
   }

   @SuppressWarnings("unchecked")
   public ENTIDADE buscarUmResultado(String namedQuery, Map<String, Object> parametros)
   {
      ENTIDADE result = null;

      try
      {
         Query query = em.createNamedQuery(namedQuery);

         if (parametros != null && !parametros.isEmpty())
         {
            popularParametrosQuery(query, parametros);
         }

         result = (ENTIDADE) query.getSingleResult();

      }
      catch (Exception e)
      {
         e.printStackTrace();
      }

      return result;
   }

   private void popularParametrosQuery(Query query, Map<String, Object> parametros)
   {

      for (Entry<String, Object> entry : parametros.entrySet())
      {
         query.setParameter(entry.getKey(), entry.getValue());
      }
   }
}
